using System;
using System.IO;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Build;
using UnityEditor.AddressableAssets.Build.DataBuilders;
using UnityEditor.AddressableAssets.Settings;
using UnityEditorInternal;
using UnityEngine;

namespace FormicArch.AssetBundleEditor
{
    public class AssetBuildMenuItem
    {
        private static readonly string assetPath = "D:/Assetbundles";
        private static string assetbundlePath = "Assets/Res";
        private static string assetbundleArtPath = "Assets/ArtRes";

        [MenuItem("Assets/Addressables/PrintDependendy")]
        private static void PrintDependency()
        {
            var depends = AssetDatabase.GetDependencies(AssetDatabase.GetAssetPath(Selection.activeObject), true);
            Debug.LogError($"获取依赖总数：{depends.Length}");
            foreach (var depend in depends)
                if (AssetDatabase.GetMainAssetTypeAtPath(depend) != typeof(MonoScript))
                    Debug.Log($"dependPath:【{depend}】");
        }

        [MenuItem("Assets/Addressables/BuildTest")]
        private static void BuildTest()
        {
            // string[] assetPaths= AssetDatabase.FindAssets("t:object", new[] {"" });
            // AssetDatabase.GetDependencies()
            if (Directory.Exists(assetPath)) Directory.Delete(assetPath, true);

            Directory.CreateDirectory(assetPath);
            BuildPipeline.BuildAssetBundles(assetPath, BuildAssetBundleOptions.UncompressedAssetBundle,
                EditorUserBuildSettings.activeBuildTarget);
        }

        [MenuItem("Tools/Addressables/ClearPrefabsWithMissScript")]
        [MenuItem("Assets/Addressables/ClearPrefabsWithMissScript")]
        public static void ClearPrefabsWithMissScript()
        {
            string[] assetPaths =
                AssetDatabase.FindAssets("t:Prefab", new[] { assetbundlePath, assetbundleArtPath });
            assetPaths = Array.ConvertAll(assetPaths, AssetDatabase.GUIDToAssetPath);
            foreach (var path in assetPaths)
            {
                bool isDeleted = false;
                GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                foreach (var trans in obj.GetComponentsInChildren<Transform>(true))
                {
                    if (PrefabUtility.IsPrefabAssetMissing(trans.gameObject))
                    {
                        Debug.LogError($"{obj.name}================引用对象丢失:{trans.gameObject.name}");
                    }

                    if (GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(trans.gameObject) > 0)
                    {
                        Debug.LogError($"{obj.name}================脚本丢失:{trans.gameObject.name}");
                        isDeleted = true;
                        GameObjectUtility.RemoveMonoBehavioursWithMissingScript(trans.gameObject);
                    }
                }

                if (isDeleted)
                {
                    EditorUtility.SetDirty(obj);
                    AssetDatabase.SaveAssetIfDirty(obj);
                }
            }
        }
        [MenuItem("Tools/Addressables/SetBuildInfo", false, 1)]
        [MenuItem("Assets/Addressables/SetBuildInfo")]
        private static void SetBuildInfo()
        {
            var assetBuildManager = new AssetBuildManager();
            assetBuildManager.GetAtlasAsset();
            assetBuildManager.GetBuildAsset();
            assetBuildManager.SetAddressable();

            // string[] assetPaths= AssetDatabase.FindAssets("t:object", new[] {"" });
            // AssetDatabase.GetDependencies()
            if (Directory.Exists(assetPath)) Directory.Delete(assetPath, true);

            Directory.CreateDirectory(assetPath);
            BuildPipeline.BuildAssetBundles(assetPath, BuildAssetBundleOptions.UncompressedAssetBundle,
                EditorUserBuildSettings.activeBuildTarget);
        }


        [MenuItem("Tools/Addressables/Build Addressables Content")]
        public static void BuildAddressables()
        {
            // AddressableAssetSettings custemSettings = AssetDatabase.LoadAssetAtPath<AddressableAssetSettings>("Assets/Path/To/YourSettings.asset");
            var settings = AddressableAssetSettingsDefaultObject.Settings;
            settings.activeProfileId = settings.profileSettings.GetProfileId("MyProfile");
            settings.ActivePlayerDataBuilderIndex =
                settings.DataBuilders.FindIndex(b => b.GetType() == typeof(CustomBuildScript));
            // settings.DataBuilders.IndexOf(
            //     settings.DataBuilders.FirstOrDefault(b => b.GetType() == typeof(CustomBuildScript)));

            AddressableAssetSettings.BuildPlayerContent(out var result);
            if (string.IsNullOrEmpty(result.Error))
                Debug.Log("Addressables Build succeeded");
            else
                Debug.LogError($"Addressables Build failed: {result.Error}");
        }

        [MenuItem("Tools/Addressables/AssemblyDefinitionSet")]
        [MenuItem("Assets/Addressables/AssemblyDefinitionSet")]
        public static void AssemblyDefinitionSet()
        {
            string[] asmdefPaths = AssetDatabase.FindAssets("t:asmdef", new[] { "Assets" });

            asmdefPaths = Array.ConvertAll(asmdefPaths, AssetDatabase.GUIDToAssetPath);
            foreach (var path in asmdefPaths)
            {
                AssemblyDefinitionImporter importer =
                    AssetImporter.GetAtPath(path) as AssemblyDefinitionImporter;
                var value = importer.GetExternalObjectMap();
            }
        }
    }

    internal class CustomBuildScript : BuildScriptBase
    {
        #region doc_CustomBuildScript

        public override bool CanBuildData<T>()
        {
            return typeof(T).IsAssignableFrom(typeof(AddressablesPlayerBuildResult));
        }

        #endregion
    }

    internal class CustomPlayModeScript : BuildScriptBase
    {
        #region doc_CustomPlayModeScript

        public override bool CanBuildData<T>()
        {
            return typeof(T).IsAssignableFrom(typeof(AddressablesPlayModeBuildResult));
        }

        #endregion
    }
}